package proyectobdii;

import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.util.LinkedList;

public class Controller_Tables {

	private Controller_Connection ctrl_connection;
	private LinkedList<Table> commonTables;
	private LinkedList<Table> diffTables;
	private LinkedList<Table> exclusiveTablesI;
	private LinkedList<Table> exclusiveTablesII;
	private Diff_Tables diff_tables;

	public Controller_Tables(Controller_Connection ctrl_connection)throws Exception {
		
		this.ctrl_connection = ctrl_connection;
		exclusiveTablesI = new LinkedList<Table>();
		DatabaseMetaData dbmdI = ctrl_connection.getDataBaseI().getConection().getMetaData();
                
		ResultSet tableBDI = dbmdI.getTables(null,null,"%",null);
		while(tableBDI.next()) {
			LinkedList <Parameter> auxColumna = new LinkedList<Parameter>();
			ResultSet colums = dbmdI.getColumns(null, null, tableBDI.getString(3), null);
                        //System.out.println("get: "+colums.getString(6));
			ResultSet pk = dbmdI.getPrimaryKeys(null, null, tableBDI.getString(3));
			ResultSet indexs = dbmdI.getIndexInfo(null, null, tableBDI.getString(3), true, false);
			LinkedList <String> pkey = new LinkedList<String>();
			while (pk.next()){
				pkey.add(pk.getString(4));
			}
			while (colums.next()){
                                
				auxColumna.add(new Parameter(colums.getString(4),colums.getString(6),colums.getString(7)));
        		}

			DataBase connectionBdI = DataBase.getInstance(ctrl_connection.getDataBaseI().getUserName(),ctrl_connection.getDataBaseI().getPassword(),ctrl_connection.getDataBaseI().getHost() , ctrl_connection.getDataBaseI().getDataBaseName());
			ResultSet triggersBDI= connectionBdI.executeQueryy("SELECT * FROM information_schema.triggers WHERE TRIGGER_SCHEMA='"+ctrl_connection.getDataBaseI().getDataBaseName()+"'");//+"' AND EVENT_OBJECT_TABLE='"+tableBDI.getString(3)+"'");
                        
			LinkedList<Trigger> triggers= new LinkedList<Trigger>();
			while (triggersBDI.next()){
				String momento=triggersBDI.getString(12);
				triggers.add(new Trigger(triggersBDI.getString(3), triggersBDI.getString(4), momento));
			}
                           
                        //System.out.println("triggers de db "+ctrl_connection.getDataBaseI().getDataBaseName()+","+triggers.toString());
			LinkedList<Unique> uniques = new LinkedList<Unique>();
                        LinkedList<Index> index = new LinkedList<Index>();
			while(indexs.next()){
				if(!indexs.getString(6).equals("PRIMARY") && indexs.getString(3).equals(tableBDI.getString(3))){
                                    uniques.add(new Unique(indexs.getString(6), indexs.getString(9)));
				}else{
                                    index.add(new Index(indexs.getString(6), indexs.getString(9)));
                                }
			}
			exclusiveTablesI.add(new Table(tableBDI.getString(3), concatenarLista(pkey), auxColumna,uniques,triggers, index));
		}

		exclusiveTablesII = new LinkedList<Table>();
		DatabaseMetaData dbmdII = ctrl_connection.getDataBaseII().getConection().getMetaData();

		ResultSet tableBDII = dbmdII.getTables(null,null,"%",null);

		while(tableBDII.next()) {
			LinkedList <Parameter> auxColumna = new LinkedList<Parameter>();
			ResultSet colums = dbmdII.getColumns(null, null, tableBDII.getString(3), null);
			ResultSet pk = dbmdII.getPrimaryKeys(null, null, tableBDII.getString(3));
			ResultSet indexs = dbmdII.getIndexInfo(null, null, tableBDII.getString(3), true, false);
                        //ResultSet index2 = dbmdII.get(null, null, tableBDII.getString(4), false, false);
			LinkedList <String> pkey = new LinkedList<String>();
			while (pk.next()){
				pkey.add(pk.getString(4));
			}

			while (colums.next()){
				auxColumna.add(new Parameter(colums.getString(4),colums.getString(6),colums.getString(7)));
			}

			DataBase connectionII = DataBase.getInstance(ctrl_connection.getDataBaseII().getUserName(),ctrl_connection.getDataBaseII().getPassword(),ctrl_connection.getDataBaseII().getHost() , ctrl_connection.getDataBaseII().getDataBaseName());
			ResultSet triggersBDII= connectionII.executeQueryy("SELECT * FROM information_schema.triggers WHERE TRIGGER_SCHEMA='"+ctrl_connection.getDataBaseII().getDataBaseName()+"'");

			LinkedList<Trigger> triggers= new LinkedList<Trigger>();
			while (triggersBDII.next()){
				String momento=triggersBDII.getString(12);
				triggers.add(new Trigger(triggersBDII.getString(3), triggersBDII.getString(4), momento));
			}
                        
                        //System.out.println("triggers de db II "+ctrl_connection.getDataBaseII().getDataBaseName()+","+triggers.toString());
			LinkedList<Unique> uniques = new LinkedList<Unique>();
                        LinkedList<Index> index = new LinkedList<Index>();
			while(indexs.next()){
                                //index2.next();
                                //System.out.println(index2.getString(6)+"/////"+index2.getString(9));
				if(!indexs.getString(6).equals("PRIMARY") && indexs.getString(3).equals(tableBDII.getString(3))){
                                    uniques.add(new Unique(indexs.getString(6), indexs.getString(9)));
				}else{
                                    index.add(new Index(indexs.getString(6), indexs.getString(9)));
                                }
			}
			exclusiveTablesII.add(new Table(tableBDII.getString(3), concatenarLista(pkey), auxColumna,uniques,triggers, index));
		}
		separarTablas();
		diff_tables = new Diff_Tables(ctrl_connection.getDataBaseI(), ctrl_connection.getDataBaseII(), commonTables, exclusiveTablesI, exclusiveTablesII, diffTables);
	}

	private void separarTablas(){
		LinkedList<Table> iguales = new LinkedList<Table>();
		LinkedList<Table> diferentes = new LinkedList<Table>();
		int i=0;
		while(i<exclusiveTablesI.size()){
			int j=0;
			while(j<exclusiveTablesII.size() && i<exclusiveTablesI.size()){
				if(exclusiveTablesI.get(i).compareTo(exclusiveTablesII.get(j))==0){
					iguales.add(exclusiveTablesI.get(i));
					exclusiveTablesI.remove(i);
					exclusiveTablesII.remove(j);
				}else if(exclusiveTablesI.get(i).compareTo(exclusiveTablesII.get(j))==1){
					diferentes.add(exclusiveTablesI.get(i));
					diferentes.add(exclusiveTablesII.get(j));
					exclusiveTablesI.remove(i);
					exclusiveTablesII.remove(j);
				}else{
					j++;
				}
			}
			i++;
		}
		commonTables = iguales;
		diffTables = diferentes;
	}
	
	public Diff_Tables getDiffTables(){
		return diff_tables;
	}

	private static String concatenarLista (LinkedList<String> lista) throws Exception{
		String aux = "";        
		while (lista.size() != 0){            
			aux += lista.getFirst();            
			if (lista.size() > 1){
				aux += ",";
			}
			lista.removeFirst();            
		}
		return aux;
	}

}
